home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / Development Tools & Languages / Dylan Related / Mindy-1.1 (sources only) / mindy-1.1 / comp / parser.y < prev    next >
Encoding:
Text File  |  1994-08-19  |  33.5 KB  |  1,216 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: parser.y,v 1.14 94/08/18 21:35:47 wlott Exp $
  27. *
  28. * This file is the grammar.
  29. *
  30. \**********************************************************************/
  31.  
  32. %{
  33. #include <stdio.h>
  34.  
  35. #include "mindycomp.h"
  36. #include "parser.h"
  37. #include "lexer.h"
  38. #include "literal.h"
  39. #include "src.h"
  40. #include "sym.h"
  41.  
  42. struct token_list {
  43.     int token;
  44.     struct token_list *next;
  45. } *yacc_recovery_list = NULL;
  46.  
  47. static void yyerror(char *);
  48. static boolean verify_symbol_aux(struct id *id, struct token *against);
  49. static void yacc_recover();
  50. static void push_yacc_recovery(int token);
  51. static void pop_yacc_recoveries(int count);
  52.  
  53. #define verify_symbol(id,sym) if (verify_symbol_aux(id,sym)) YYERROR
  54.  
  55. %}
  56.  
  57. %union {
  58.     struct _nothing *nothing;
  59.     struct token *token;
  60.     struct body *body;
  61.     struct constituent *constituent;
  62.     struct expr *expr;
  63.     struct bindings *bindings;
  64.     struct param_list *param_list;
  65.     struct param *param;
  66.     struct keyword_param *keyword_param;
  67.     struct id *id;
  68.     struct local_methods *local_methods;
  69.     struct method *method;
  70.     struct binop_series *binop_series;
  71.     struct binop *binop;
  72.     struct literal *literal;
  73.     struct arglist *arglist;
  74.     struct argument *argument;
  75.     struct plist *plist;
  76.     struct return_type_list *return_type_list;
  77.     struct literal_list *literal_list;
  78.     struct block_epilog *block_epilog;
  79.     struct condition_body *condition_body;
  80.     struct incomplete_condition_body *incomplete_condition_body;
  81.     struct condition_clause *condition_clause;
  82.     struct for_header *for_header;
  83.     struct exception_clauses *exception_clauses;
  84.     struct exception_clause *exception_clause;
  85.     struct for_clause *for_clause;
  86.     struct to_part *to_part;
  87.     struct superclass_list *superclass_list;
  88.     struct class_guts *class_guts;
  89.     struct slot_spec *slot_spec;
  90.     struct initarg_spec *initarg_spec;
  91.     boolean bool;
  92.     struct inherited_spec *inherited_spec;
  93.     enum slot_allocation slot_allocation;
  94.     struct gf_suffix *gf_suffix;
  95.     flags_t flags;
  96.     struct else_part *else_part;
  97.  
  98.     struct defnamespace_constituent *defnamespace_constituent;
  99.     struct variable_names *variable_names;
  100.     struct use_clause *use_clause;
  101.     struct use_options *use_options;
  102.     struct use_option *use_option;
  103.     struct import_option *import_option;
  104.     struct renamings *renamings;
  105. }
  106.  
  107. %token <token> BOGUS
  108. %token <token> SYMBOL
  109. %token <token> KEYWORD
  110. %token <token> SYMBOL_LITERAL
  111. %token <token> SHARP_T
  112. %token <token> SHARP_F
  113. %token <token> STRING
  114. %token <token> CHARACTER
  115. %token <token> INTEGER
  116. %token <token> FLOAT
  117. %token <token> BINARY_OPERATOR
  118. %token <token> LPAREN
  119. %token <token> RPAREN
  120. %token <token> COMMA
  121. %token <token> DOT
  122. %token <token> SEMI
  123. %token <token> LBRACKET
  124. %token <token> RBRACKET
  125. %token <token> LBRACE
  126. %token <token> RBRACE
  127. %token <token> COLON_COLON
  128. %token <token> MINUS
  129. %token <token> TILDE
  130. %token <token> EQUAL
  131. %token <token> EQUAL_EQUAL
  132. %token <token> ARROW
  133. %token <token> SHARP_PAREN
  134. %token <token> SHARP_BRACKET
  135. %token <token> NEXT
  136. %token <token> REST
  137. %token <token> KEY
  138. %token <token> ALL_KEYS
  139. %token <token> ABOVE
  140. %token <token> ABSTRACT
  141. %token <token> DBEGIN
  142. %token <token> BELOW
  143. %token <token> BLOCK
  144. %token <token> BY
  145. %token <token> CASE
  146. %token <token> CLASS
  147. %token <token> CLEANUP
  148. %token <token> CONCRETE
  149. %token <token> CONSTANT
  150. %token <token> DEFINE
  151. %token <token> ELSE
  152. %token <token> ELSEIF
  153. %token <token> END
  154. %token <token> EXCEPTION
  155. %token <token> FINALLY
  156. %token <token> FOR
  157. %token <token> FREE
  158. %token <token> FROM
  159. %token <token> GENERIC
  160. %token <token> HANDLER
  161. %token <token> IF
  162. %token <token> IN
  163. %token <token> INHERITED
  164. %token <token> INSTANCE
  165. %token <token> KEYED_BY
  166. %token <token> KEYWORD_RESERVED_WORD
  167. %token <token> LET
  168. %token <token> LOCAL
  169. %token <token> METHOD
  170. %token <token> OPEN
  171. %token <token> OTHERWISE
  172. %token <token> PRIMARY
  173. %token <token> REQUIRED
  174. %token <token> SEAL
  175. %token <token> SEALED
  176. %token <token> SELECT
  177. %token <token> SLOT
  178. %token <token> SUBCLASS
  179. %token <token> THEN
  180. %token <token> TO
  181. %token <token> UNLESS
  182. %token <token> UNTIL
  183. %token <token> VARIABLE
  184. %token <token> VIRTUAL
  185. %token <token> WHILE
  186.  
  187. %token <token> MODULE
  188. %token <token> LIBRARY
  189. %token <token> EXPORT
  190. %token <token> CREATE
  191. %token <token> USE
  192. %token <token> ALL
  193.  
  194. /* These tokens sometimes have special significance and are sometimes just
  195.    keywords */
  196. %token <token> PREFIX_OPTION
  197. %token <token> IMPORT_OPTION
  198. %token <token> EXCLUDE_OPTION
  199. %token <token> EXPORT_OPTION
  200. %token <token> RENAME_OPTION
  201. %type  <token> keyword keyword_opt
  202.  
  203. %type <nothing> dylan_program block_opt case_opt if_opt for_opt select_opt
  204. %type <nothing> unless_opt until_opt while_opt class_opt method_opt semi_opt
  205. %type <nothing> arrow_opt
  206. %type <token> symbol_opt
  207. %type <body> body body_opt constituents cleanup_part
  208. %type <body> final_part final_part_opt
  209. %type <constituent> constituent defining_form local_declaration
  210. %type <constituent> class_definition generic_function_definition
  211. %type <bindings> bindings
  212. %type <param_list> variables gf_parameters
  213. %type <param_list> more_gf_parameters gf_rest_parameters
  214. %type <param_list> gf_keyword_parameters_list gf_keyword_parameters_opt
  215. %type <param_list> gf_keyword_parameters parameters more_parameters
  216. %type <param_list> next_parameters rest_parameters keyword_parameters_list
  217. %type <param_list> keyword_parameters_opt keyword_parameters
  218. %type <param> variable positional_parameter
  219. %type <keyword_param> keyword_parameter gf_keyword_parameter
  220. %type <id> next_parameter rest_parameter
  221. %type <local_methods> local_methods
  222. %type <method> local_method anonymous_method named_method method_description
  223. %type <expr> expression operand leaf statement by_part by_part_opt 
  224. %type <expr> slot_type_opt return_type_element keyword_parameter_type
  225. %type <expr> keyword_parameter_default
  226. %type <binop_series> binop_series
  227. %type <binop> binop
  228. %type <arglist> arguments_opt arguments
  229. %type <argument> argument
  230. %type <plist> property_list_opt property_list
  231. %type <return_type_list> return_type return_type_list return_type_list_head
  232. %type <literal> constant concat_string literal dotted_list
  233. %type <literal_list> literals_opt literals
  234. %type <block_epilog> block_epilog block_epilog_opt
  235. %type <condition_body> condition_body complete_condition_clauses
  236. %type <for_header> for_header
  237. %type <exception_clauses> exception_clauses_opt exception_clauses
  238. %type <exception_clause> exception_clause
  239. %type <incomplete_condition_body> incomplete_condition_clauses
  240. %type <condition_clause> condition_clause
  241. %type <for_clause> for_clause
  242. %type <to_part> to_part_opt
  243. %type <superclass_list> superclasses
  244. %type <class_guts> class_guts_opt class_guts
  245. %type <slot_spec> slot_spec
  246. %type <initarg_spec> initarg_spec
  247. %type <bool> required_opt
  248. %type <inherited_spec> inherited_spec
  249. %type <slot_allocation> allocation
  250. %type <gf_suffix> gf_suffix
  251. %type <flags> flags 
  252. %type <else_part> else_part else_part_opt
  253.  
  254. %type <constituent> module_definition library_definition 
  255. %type <defnamespace_constituent> module_clauses_opt module_clauses
  256. %type <defnamespace_constituent> library_clauses_opt library_clauses
  257. %type <nothing> module_opt library_opt
  258. %type <variable_names> export_clause create_clause 
  259. %type <use_clause> use_clause 
  260. %type <use_options> module_use_options 
  261. %type <use_option> module_use_option prefix_option exclude_option
  262. %type <use_option> rename_option export_option import_option
  263. %type <renamings> rename_specs
  264. %type <import_option> imports imports_opt
  265. %type <variable_names> variable_name_set variable_names
  266.  
  267. %%
  268.  
  269. dylan_program:
  270.     { push_yacc_recovery(SEMI); }
  271.     body    { Program = $2; $$ = NULL; }
  272. ;
  273.  
  274. body:
  275.     constituents semi_opt    { $$ = $1; }
  276. ;
  277.  
  278. body_opt:
  279.     /* epsilon */    { $$ = make_body(); }
  280.     |    body        { $$ = $1; }
  281. ;
  282.  
  283.  
  284. constituents:
  285.     constituent
  286.     { $$ = add_constituent(make_body(), $1); }
  287.     |    constituents SEMI constituent
  288.     { free($2); $$ = add_constituent($1, $3); }
  289. ;
  290.  
  291. constituent:
  292.     defining_form        { $$ = $1; }
  293.     |    local_declaration    { $$ = $1; }
  294.     |    expression        { $$ = make_expr_constituent($1); }
  295.     |   error            { $$ = make_error_constituent(); }
  296. ;
  297.  
  298. defining_form:
  299.     DEFINE flags CLASS class_definition
  300.     { free($1); free($3); $$ = set_class_flags($2, $4); }
  301.     |    DEFINE CONSTANT bindings
  302.     { free($1); $$ = make_define_constant($2->line, $3); free($2); }
  303.     |    DEFINE flags GENERIC generic_function_definition
  304.     { free($1); free($3); $$ = set_generic_flags($2, $4); }
  305.     |    DEFINE flags METHOD named_method
  306.     { free($1); free($3); $$ = make_define_method($2, $4); }
  307.     |    DEFINE VARIABLE bindings
  308.     { free($1); $$ = make_define_variable($2->line, $3); free($2); }
  309.     |    DEFINE MODULE module_definition
  310.     { free($1); free($2); $$ = $3; }
  311.     |    DEFINE LIBRARY library_definition
  312.     { free($1); free($2); $$ = $3; }
  313. ;
  314.  
  315. flags:
  316.     /* epsilon */ { $$ = 0; }
  317.     |    flags SEALED { free($2); $$ = $1 | flag_SEALED; }
  318.     |    flags OPEN { free($2); $$ = $1 | flag_OPEN; }
  319.     |    flags ABSTRACT { free($2); $$ = $1 | flag_ABSTRACT; }
  320.     |    flags CONCRETE { free($2); $$ = $1 | flag_CONCRETE; }
  321.     |    flags PRIMARY { free($2); $$ = $1 | flag_PRIMARY; }
  322.     |    flags FREE { free($2); $$ = $1 | flag_FREE; }
  323. ;    
  324.  
  325. local_declaration:
  326.     LET bindings
  327.     { free($1); $$ = make_let($2); }
  328.     |    LET HANDLER SYMBOL EQUAL expression
  329.     { free($1); free($2); free($4);
  330.       $$ = make_handler(make_varref(make_id($3)), $5, NULL);
  331.     }
  332.     |    LET HANDLER LPAREN expression property_list_opt RPAREN EQUAL expression
  333.     { free($1); free($2); free($3); free($6); free($7);
  334.       $$ = make_handler($4, $8, $5);
  335.     }
  336.     |    LOCAL local_methods
  337.     { free($1); $$ = make_local_constituent($2); }
  338. ;
  339.  
  340. bindings:
  341.     variable EQUAL expression
  342.     { free($2); $$ = make_bindings(push_param($1,make_param_list()), $3); }
  343.     |    LPAREN variables RPAREN EQUAL expression
  344.     { free($1); free($3); free($4); $$ = make_bindings($2, $5); }
  345. ;
  346.  
  347. variables:
  348.     rest_parameter
  349.     { $$ = set_rest_param(make_param_list(), $1); }
  350.     |    variable
  351.     { $$ = push_param($1, make_param_list()) }
  352.     |    variable COMMA variables
  353.     { free($2); $$ = push_param($1, $3); }
  354. ;
  355.  
  356. variable:
  357.     SYMBOL { $$ = make_param(make_id($1), NULL); }
  358.     |    SYMBOL COLON_COLON operand
  359.     { free($2); $$ = make_param(make_id($1), $3); }
  360. ;
  361.  
  362. local_methods:
  363.     local_method { $$ = add_local_method(make_local_methods(), $1); }
  364.     |    local_methods COMMA local_method
  365.     { free($2); $$ = add_local_method($1, $3); }
  366. ;
  367.  
  368. local_method:
  369.     method_opt named_method { $$ = $2; }
  370. ;
  371.  
  372. keyword:
  373.     KEYWORD
  374.     |    PREFIX_OPTION
  375.     |    IMPORT_OPTION
  376.     |    EXCLUDE_OPTION
  377.     |    EXPORT_OPTION
  378.     |    RENAME_OPTION
  379. ;
  380.  
  381. expression:
  382.     keyword { $$ = make_literal_ref(parse_keyword_token($1)); }
  383.     |    operand { $$ = $1; }
  384.     |    operand binop_series
  385.     { $$ = make_binop_series_expr($1, $2); }
  386. ;
  387.  
  388. binop_series:
  389.     binop operand { $$ = add_binop(make_binop_series(), $1, $2); }
  390.     |    binop_series binop operand { $$ = add_binop($1, $2, $3); }
  391. ;
  392.  
  393. binop:
  394.     BINARY_OPERATOR { $$ = make_binop(make_id($1)); }
  395.     |    MINUS { $$ = make_binop(make_id($1)); }
  396.     |    EQUAL { $$ = make_binop(make_id($1)); }
  397.     |    EQUAL_EQUAL { $$ = make_binop(make_id($1)); }
  398. ;
  399.  
  400. operand:
  401.     MINUS operand { free($1); $$ = make_negate($2); }
  402.     |    TILDE operand { free($1); $$ = make_not($2); }
  403.     |    leaf { $$ = $1; }
  404. ;
  405.  
  406. leaf:
  407.     constant { $$ = make_literal_ref($1); }
  408.     |    SYMBOL { $$ = make_varref(make_id($1)); }
  409.     |    leaf LBRACKET arguments_opt RBRACKET
  410.     { free($2); free($4); $$ = make_aref_or_element($1, $3); }
  411.     |    leaf LPAREN arguments_opt RPAREN
  412.     { free($2); free($4); $$ = make_function_call($1, $3); }
  413.     |    anonymous_method { $$ = make_method_ref($1); }
  414.     |    leaf DOT SYMBOL
  415.     { free($2);
  416.       $$ = make_dot_operation($1, make_varref(make_id($3)));
  417.     }
  418.     |    LPAREN expression RPAREN { $$ = $2; free($1); free($3); }
  419.     |    statement { $$ = $1; }
  420. ;
  421.  
  422. arguments_opt:
  423.     /* epsilon */ { $$ = make_argument_list(); }
  424.     |    arguments { $$ = $1; }
  425. ;
  426.  
  427. arguments:
  428.     argument { $$ = add_argument(make_argument_list(), $1); }
  429.     |    arguments COMMA argument { free($2); $$ = add_argument($1, $3); }
  430. ;
  431.  
  432. argument:
  433.     expression { $$ = make_argument($1); }
  434.     |    keyword expression
  435.     { $$ = make_keyword_argument($1, $2); }
  436. ;
  437.  
  438. constant:
  439.     SHARP_T { $$ = parse_true_token($1); }
  440.     |    SHARP_F { $$ = parse_false_token($1); }
  441.     |    concat_string { $$ = $1; }
  442.     |    CHARACTER { $$ = parse_character_token($1); }
  443.     |    INTEGER { $$ = parse_integer_token($1); }
  444.     |    FLOAT { $$ = parse_float_token($1); }
  445.     |    SYMBOL_LITERAL { $$ = parse_keyword_token($1); }
  446.     |    SHARP_PAREN dotted_list RPAREN
  447.     { free($1); free($3); $$ = $2; }
  448.     |    SHARP_PAREN literals_opt RPAREN
  449.     { free($1); free($3); $$ = make_list_literal($2); }
  450.     |    SHARP_BRACKET literals_opt RBRACKET
  451.     { free($1); free($3); $$ = make_vector_literal($2); }
  452. ;
  453.  
  454. concat_string:
  455.     STRING             { $$ = parse_string_token($1); }
  456.     |    concat_string STRING    { $$ = concat_string_token($1, $2); }
  457.  
  458. dotted_list:
  459.     literals DOT literal
  460.     { free($2); $$ = make_dotted_list_literal($1, $3); }
  461. ;
  462.  
  463. literals_opt:
  464.     /* epsilon */
  465.     { $$ = make_literal_list(); }
  466.     |    literals
  467.     { $$ = $1; }
  468. ;
  469.  
  470. literals:
  471.     literal { $$ = add_literal(make_literal_list(), $1); }
  472.     |    literals COMMA literal
  473.     { free($2); $$ = add_literal($1, $3); }
  474. ;
  475.  
  476. literal:
  477.     constant { $$ = $1; }
  478.     |    keyword { $$ = parse_keyword_token($1); }
  479. ;
  480.  
  481. statement:
  482.     DBEGIN { push_yacc_recovery(END) }
  483.     body_opt END
  484.     { free($1); free($4); $$ = make_body_expr($3);
  485.           pop_yacc_recoveries(1); }
  486.     |    BLOCK LPAREN symbol_opt RPAREN { push_yacc_recovery(END);
  487.                      push_yacc_recovery(CLEANUP);
  488.                      push_yacc_recovery(EXCEPTION); }
  489.     body block_epilog_opt END block_opt
  490.     { free($2); free($4); free($8); pop_yacc_recoveries(3); 
  491.       $$ = make_block($1->line, $3 ? make_id($3) : NULL, $6, $7);
  492.       free($1);
  493.     }
  494.     |    CASE { push_yacc_recovery(END); }
  495.     condition_body END case_opt
  496.     { free($1); free($4); $$ = make_case($3);
  497.           pop_yacc_recoveries(1); }
  498.     |    IF LPAREN expression RPAREN { push_yacc_recovery(END);
  499.                       push_yacc_recovery(ELSE); }
  500.     body else_part_opt END if_opt
  501.     { free($1); free($2); free($4); free($8); $$ = make_if($3, $6, $7);
  502.           pop_yacc_recoveries(2); }
  503.     |    FOR LPAREN for_header RPAREN { push_yacc_recovery(END);
  504.                        push_yacc_recovery(FINALLY); }
  505.     body_opt final_part_opt END for_opt
  506.     { free($1); free($2); free($4); free($8); $$ = make_for($3, $6, $7);
  507.           pop_yacc_recoveries(2); }
  508.     |    SELECT LPAREN expression by_part_opt RPAREN {push_yacc_recovery(END);}
  509.         condition_body END select_opt
  510.     { free($1);free($2);free($5);free($8); $$ = make_select($3, $4, $7);
  511.           pop_yacc_recoveries(1); }
  512.     |    UNLESS LPAREN expression RPAREN { push_yacc_recovery(END); }
  513.     body END unless_opt
  514.     { free($1);free($2);free($4);free($7);
  515.       $$ = make_if($3, NULL, make_else(0, $6));
  516.           pop_yacc_recoveries(1); }
  517.     |    UNTIL LPAREN expression RPAREN { push_yacc_recovery(END); }
  518.         body_opt END until_opt
  519.     { free($1);free($2);free($4);free($7); pop_yacc_recoveries(1);
  520.       $$ = make_for(make_for_header($3), $6, NULL);
  521.     }
  522.     |    WHILE LPAREN expression RPAREN { push_yacc_recovery(END); }
  523.     body_opt END while_opt
  524.     { free($1);free($2);free($4);free($7);pop_yacc_recoveries(1);
  525.       $$ = make_for(make_for_header(make_not($3)), $6, NULL);
  526.     }
  527. ;
  528.  
  529. block_epilog_opt:
  530.     /* epsilon */ { $$ = NULL; }
  531.     |    block_epilog { $$ = $1; }
  532. ;
  533.  
  534. block_epilog:
  535.     exception_clauses_opt cleanup_part exception_clauses_opt
  536.     { $$ = make_block_epilog($1, $2, $3); }
  537.     |    exception_clauses
  538.     { $$ = make_block_epilog($1, NULL, NULL); }
  539. ;
  540.  
  541. condition_body:
  542.     complete_condition_clauses { $$ = $1; }
  543. ;
  544.  
  545. for_header:
  546.     UNTIL expression
  547.     { free($1); $$ = make_for_header($2); }
  548.     |    WHILE expression
  549.     { free($1); $$ = make_for_header(make_not($2)); }
  550.     |    for_clause
  551.     { $$ = push_for_clause($1, make_for_header(NULL)); }
  552.     |    for_clause COMMA for_header
  553.     { free($2); $$ = push_for_clause($1, $3); }
  554. ;
  555.  
  556. exception_clauses_opt:
  557.     /* epsilon */ { $$ = NULL; }
  558.     |    exception_clauses { $$ = $1; }
  559. ;
  560.  
  561. exception_clauses:
  562.     exception_clause
  563.     { $$ = add_exception_clause(make_exception_clauses(), $1); }
  564.     |    exception_clauses exception_clause
  565.     { $$ = add_exception_clause($1, $2); }
  566. ;
  567.  
  568. exception_clause:
  569.     EXCEPTION SYMBOL body
  570.     { free($1);
  571.       $$ = make_exception_clause(make_varref(make_id($2)),
  572.                      NULL, NULL, $3);
  573.     }
  574.     |    EXCEPTION LPAREN expression property_list_opt RPAREN body
  575.     { free($1); free($2); free($5);
  576.       $$ = make_exception_clause($3, NULL, $4, $6);
  577.     }
  578.     |    EXCEPTION LPAREN SYMBOL COLON_COLON expression property_list_opt RPAREN
  579.         body
  580.     { free($1); free($2); free($4); free($7);
  581.       $$ = make_exception_clause($5, make_id($3), $6, $8);
  582.     }
  583. ;
  584.  
  585. complete_condition_clauses:
  586.     OTHERWISE arrow_opt body
  587.     { free($1);
  588.       $$ = push_condition_clause(make_otherwise_condition_clause($3),
  589.                      NULL);
  590.     }
  591.     |    condition_clause semi_opt
  592.     { $$ = push_condition_clause($1, NULL); }
  593.     |    condition_clause SEMI complete_condition_clauses
  594.     { free($2); $$ = push_condition_clause($1, $3); }
  595.     |    condition_clause SEMI incomplete_condition_clauses
  596.     { free($2); $$ = complete_condition_clauses($1, $3); }
  597. ;
  598.  
  599. incomplete_condition_clauses:
  600.     constituent semi_opt
  601.     { $$ = make_incomplete_condition_clauses($1, NULL); }
  602.     |    constituent SEMI complete_condition_clauses
  603.     { free($2); $$ = make_incomplete_condition_clauses($1, $3); }
  604.     |    constituent SEMI incomplete_condition_clauses
  605.     { free($2); $$ = push_condition_constituent($1, $3); }
  606. ;
  607.  
  608. condition_clause:
  609.     expression ARROW constituent
  610.     { free($2); $$ = push_condition($1, make_condition_clause($3)); }
  611.     |    expression COMMA condition_clause
  612.     { free($2); $$ = push_condition($1, $3); }
  613. ;
  614.  
  615. for_clause:
  616.     variable EQUAL expression THEN expression
  617.     { free($2); free($4);
  618.     $$=make_equal_then_for_clause(push_param($1,make_param_list()),$3,$5);}
  619.     |    LPAREN variables RPAREN EQUAL expression THEN expression
  620.     { free($1); free($3); free($4); free($6);
  621.       $$ = make_equal_then_for_clause($2, $5, $7); }
  622.     |    variable IN expression 
  623.     { free($2); $$ = make_in_for_clause($1, NULL, $3); }
  624.     |    variable KEYED_BY variable IN expression
  625.     { free($2); free($4); $$ = make_in_for_clause($1, $3, $5); }
  626.     |    variable FROM expression to_part_opt by_part_opt
  627.     { free($2); $$ = make_from_for_clause($1, $3, $4, $5); }
  628. ;
  629.  
  630. by_part:    BY expression { free($1); $$ = $2; } ;
  631. cleanup_part:    CLEANUP body { free($1); $$ = $2; } ;
  632. final_part:    FINALLY body { free($1); $$ = $2; } ;
  633.  
  634. else_part:
  635.     ELSE body { $$ = make_else($1->line, $2); free($1); }
  636.     |    ELSEIF LPAREN expression RPAREN body else_part_opt
  637.     { free($2); free($4);
  638.       $$ = make_else($1->line, make_expr_body(make_if($3, $5, $6)));
  639.       free($1); 
  640.     }
  641. ;
  642.  
  643. to_part_opt:
  644.     /* epsilon */ { $$ = NULL; }
  645.     |    TO expression { free($1); $$ = make_to($2); }
  646.     |    ABOVE expression { free($1); $$ = make_above($2); }
  647.     |    BELOW expression { free($1); $$ = make_below($2); }
  648. ;
  649.  
  650. class_definition:
  651.     SYMBOL LPAREN superclasses RPAREN
  652.         class_guts_opt END class_opt symbol_opt
  653.     { struct id *id = make_id($1);
  654.       verify_symbol(id, $8); free($2); free($4); free($6);
  655.       $$ = make_class_definition(id, $3, $5);
  656.     }
  657. ;
  658.  
  659. superclasses:
  660.     expression
  661.     { $$ = add_superclass(make_superclass_list(), $1); }
  662.     |    superclasses COMMA expression
  663.     { free($2); $$ = add_superclass($1, $3); }
  664. ;
  665.  
  666. class_guts_opt:
  667.     /* epsilon */ { $$ = NULL; }
  668.     |    class_guts semi_opt { $$ = $1; }
  669. ;
  670.  
  671. class_guts:
  672.     slot_spec
  673.     { $$ = add_slot_spec(make_class_guts(), $1); }
  674.     |    initarg_spec
  675.     { $$ = add_initarg_spec(make_class_guts(), $1); }
  676.     |    inherited_spec
  677.     { $$ = add_inherited_spec(make_class_guts(), $1); }
  678.     |    class_guts SEMI slot_spec
  679.     { free($2); $$ = add_slot_spec($1, $3); }
  680.     |    class_guts SEMI initarg_spec
  681.     { free($2); $$ = add_initarg_spec($1, $3); }
  682.     |    class_guts SEMI inherited_spec
  683.     { free($2); $$ = add_inherited_spec($1, $3); }
  684. ;
  685.  
  686. slot_spec:
  687.     flags allocation SLOT SYMBOL slot_type_opt property_list_opt
  688.     {
  689.         int line = $3->line;
  690.         free($3);
  691.         $$ = make_slot_spec(line, $1, $2, $4 ? make_id($4) : NULL, $5, $6);
  692.     }
  693. ;
  694.  
  695. initarg_spec:
  696.     required_opt KEYWORD_RESERVED_WORD KEYWORD property_list_opt
  697.     { free($2); $$ = make_initarg_spec($1, $3, $4); }
  698. ;
  699.  
  700. required_opt:
  701.     REQUIRED { free($1); $$ = TRUE; }
  702.     |    /* epsilon */ { $$ = FALSE; }
  703. ;
  704.  
  705. inherited_spec:
  706.     INHERITED SLOT SYMBOL property_list_opt
  707.     { free($1); free($2); $$ = make_inherited_spec(make_id($3), $4); }
  708. ;
  709.  
  710.  
  711. allocation:
  712.     /* epsilon */ { $$ = alloc_INSTANCE; }
  713.     |    INSTANCE { free($1); $$ = alloc_INSTANCE; }
  714.     |    CLASS { free($1); $$ = alloc_CLASS; }
  715.     |    SUBCLASS { free($1); $$ = alloc_SUBCLASS; }
  716.     |    CONSTANT { free($1); $$ = alloc_CONSTANT; }
  717.     |    VIRTUAL { free($1); $$ = alloc_VIRTUAL; }
  718. ;
  719.  
  720. slot_type_opt:
  721.     /* epsilon */ { $$ = NULL; }
  722.     |    COLON_COLON expression { free($1); $$ = $2; }
  723. ;
  724.  
  725. property_list_opt:
  726.     /* epsilon */ { $$ = make_property_list(); }
  727.     |    property_list { $$ = $1; }
  728. ;
  729.  
  730. property_list:
  731.     COMMA keyword expression
  732.     { free($1); $$ = add_property(make_property_list(), $2, $3); }
  733.     |    property_list COMMA keyword expression
  734.     { free($2); $$ = add_property($1, $3, $4); }
  735. ;
  736.  
  737. generic_function_definition:
  738.     SYMBOL LPAREN gf_parameters RPAREN gf_suffix
  739.     { free($2); free($4);
  740.       $$ = make_define_generic(make_id($1), $3, $5);
  741.     }
  742. ;
  743.  
  744. gf_suffix:
  745.     property_list_opt
  746.     { $$ = make_gf_suffix(NULL, $1); }
  747.     |    ARROW return_type_element property_list_opt
  748.     { free($1);
  749.       $$ = make_gf_suffix
  750.               (add_return_type(make_return_type_list(FALSE, NULL), $2),
  751.            $3);
  752.     }
  753.     |    ARROW LPAREN return_type_list RPAREN property_list_opt
  754.     { free($1); free($2); free($4); $$ = make_gf_suffix($3, $5); }
  755. ;
  756.  
  757. gf_parameters:
  758.     /* epsilon */ { $$ = make_param_list(); }
  759.     |    positional_parameter more_gf_parameters
  760.     { $$ = push_param($1, $2); }
  761.     |    gf_rest_parameters { $$ = $1; }
  762. ;
  763.  
  764. more_gf_parameters:
  765.     /* epsilon */
  766.     { $$ = make_param_list(); }
  767.     |    COMMA positional_parameter more_gf_parameters
  768.     { free($1); $$ = push_param($2, $3); }
  769.     |    COMMA gf_rest_parameters
  770.     { free($1); $$ = $2; }
  771. ;
  772.  
  773. gf_rest_parameters:
  774.     rest_parameter
  775.     { $$ = set_rest_param(make_param_list(), $1); }
  776.     |    rest_parameter COMMA gf_keyword_parameters_list
  777.     { free($2); $$ = set_rest_param($3, $1); }
  778.     |    gf_keyword_parameters_list
  779.     { $$ = $1; }
  780. ;
  781.  
  782. gf_keyword_parameters_list:
  783.     KEY gf_keyword_parameters_opt { free($1); $$ = $2; }
  784.     |    ALL_KEYS { free($1); $$ = allow_all_keywords(make_param_list()); }
  785. ;
  786.  
  787. gf_keyword_parameters_opt:
  788.     /* epsilon */ { $$ = allow_keywords(make_param_list()); }
  789.     |    gf_keyword_parameters { $$ = $1; }
  790. ;
  791.  
  792. gf_keyword_parameters:
  793.     gf_keyword_parameter
  794.     { $$ = push_keyword_param($1, allow_keywords(make_param_list())); }
  795.     |    gf_keyword_parameter COMMA ALL_KEYS
  796.     { free($2); free($3);
  797.       $$ = push_keyword_param($1, allow_all_keywords(make_param_list())); }
  798.     |    gf_keyword_parameter COMMA gf_keyword_parameters
  799.     { free($2); $$ = push_keyword_param($1, $3); }
  800. ;
  801.  
  802. gf_keyword_parameter:
  803.     keyword symbol_opt keyword_parameter_type
  804.     { $$ = make_keyword_param($1, $2 ? make_id($2) : NULL, $3, NULL); }
  805.     |    SYMBOL keyword_parameter_type
  806.     { $$ = make_keyword_param(NULL, make_id($1), $2, NULL); }
  807. ;
  808.  
  809. anonymous_method:
  810.     METHOD method_description END method_opt
  811.     { free($3); $$ = set_method_source($1, $2); }
  812. ;
  813.  
  814. named_method:
  815.     SYMBOL method_description END method_opt symbol_opt
  816.     { struct id *id = make_id($1);
  817.       free($3); verify_symbol(id, $5);
  818.       $$ = set_method_name(id, $2);
  819.     }
  820. ;
  821.  
  822. method_description:
  823.     LPAREN parameters RPAREN return_type SEMI body
  824.     { free($1); free($3); free($5);
  825.       $$ = make_method_description($2, $4, $6);
  826.     }
  827.     |    LPAREN parameters RPAREN return_type semi_opt
  828.     { free($1); free($3);
  829.       $$ = make_method_description($2, $4, make_body());
  830.     }
  831.     |    LPAREN parameters RPAREN semi_opt body_opt
  832.     { free($1); free($3);
  833.       $$ = make_method_description($2, NULL, $5);
  834.     }
  835. ;
  836.  
  837. return_type:
  838.     ARROW return_type_list
  839.     { free($1); $$ = $2; }
  840.     |    ARROW LPAREN return_type_list RPAREN
  841.     { free($1); free($2); free($4); $$ = $3; }
  842. ;
  843.  
  844. return_type_list:
  845.     /* epsilon */
  846.     { $$ = make_return_type_list(FALSE, NULL); }
  847.     |    REST return_type_element
  848.     { free($1); $$ = make_return_type_list(TRUE, $2); }
  849.     |    return_type_list_head
  850.     { $$ = $1; }
  851.     |    return_type_list_head COMMA REST return_type_element
  852.     { free($2); free($3); $$ = set_return_type_rest_type($1, $4); }
  853. ;
  854.  
  855. return_type_list_head:
  856.     return_type_element
  857.     { $$ = add_return_type(make_return_type_list(FALSE, NULL), $1); }
  858.     |    return_type_list_head COMMA return_type_element
  859.     { free($2); $$ = add_return_type($1, $3); }
  860. ;
  861.  
  862. return_type_element:
  863.     SYMBOL { free($1); $$ = NULL; }
  864.     |    SYMBOL COLON_COLON expression { free($1); free($2); $$ = $3; }
  865. ;
  866.  
  867. parameters:
  868.     /* epsilon */ { $$ = make_param_list(); }
  869.     |    positional_parameter more_parameters { $$ = push_param($1, $2); }
  870.     |    next_parameters { $$ = $1; }
  871. ;
  872.  
  873. more_parameters:
  874.     /* epsilon */
  875.     { $$ = make_param_list(); }
  876.     |    COMMA positional_parameter more_parameters
  877.     { free($1); $$ = push_param($2, $3); }
  878.     |    COMMA next_parameters
  879.     { free($1); $$ = $2; }
  880. ;
  881.  
  882. positional_parameter:
  883.     SYMBOL
  884.     { $$ = make_param(make_id($1), NULL); }
  885.     |    SYMBOL COLON_COLON expression
  886.     { free($2); $$ = make_param(make_id($1), $3); }
  887.     |    SYMBOL EQUAL_EQUAL expression
  888.     { free($2); $$ = make_param(make_id($1), make_singleton($3)); }
  889. ;
  890.  
  891. next_parameters:
  892.     next_parameter
  893.     { $$ = set_next_param(make_param_list(), $1); }
  894.     |    next_parameter COMMA rest_parameters
  895.     { free($2); $$ = set_next_param($3, $1); }
  896.     |    rest_parameters
  897.     { $$ = $1; }
  898. ;
  899.  
  900. next_parameter:
  901.     NEXT SYMBOL { free($1); $$ = make_id($2); }
  902. ;
  903.  
  904. rest_parameters:
  905.     rest_parameter
  906.     { $$ = set_rest_param(make_param_list(), $1); }
  907.     |    rest_parameter COMMA keyword_parameters_list
  908.     { free($2); $$ = set_rest_param($3, $1); }
  909.     |    keyword_parameters_list
  910.     { $$ = $1; }
  911. ;
  912.  
  913. rest_parameter:
  914.     REST SYMBOL { free($1); $$ = make_id($2); }
  915. ;
  916.  
  917. keyword_parameters_list:
  918.     KEY keyword_parameters_opt
  919.     { free($1); $$ = $2; }
  920.     |    ALL_KEYS
  921.     { free($1); $$ = allow_all_keywords(make_param_list()); }
  922. ;
  923.  
  924. keyword_parameters_opt:
  925.     /* epsilon */ { $$ = allow_keywords(make_param_list()); }
  926.     |    COMMA ALL_KEYS
  927.     { free($1); free($2); $$ = allow_all_keywords(make_param_list()); }
  928.     |    keyword_parameters { $$ = $1; }
  929. ;
  930.  
  931. keyword_parameters:
  932.     keyword_parameter
  933.     { $$ = push_keyword_param($1, allow_keywords(make_param_list())); }
  934.     |    keyword_parameter COMMA ALL_KEYS
  935.     { free($2); free($3);
  936.       $$ = push_keyword_param($1, allow_all_keywords(make_param_list())); }
  937.     |    keyword_parameter COMMA keyword_parameters
  938.     { free($2); $$ = push_keyword_param($1, $3); }
  939. ;
  940.  
  941. keyword_parameter:
  942.     keyword_opt SYMBOL keyword_parameter_type keyword_parameter_default
  943.     { $$ = make_keyword_param($1, make_id($2), $3, $4); }
  944.     |    keyword_opt SYMBOL LPAREN expression RPAREN
  945.     { free($3); free($5);
  946.       $$ = make_keyword_param($1, make_id($2), NULL, $4); }
  947. ;
  948.  
  949. keyword_opt:
  950.     /* epsilon */ { $$ = NULL; }
  951.     |    keyword { $$ = $1; }
  952. ;    
  953.  
  954. keyword_parameter_type:
  955.     /* epsilon */ { $$ = NULL; }
  956.     |    COLON_COLON operand { free($1); $$ = $2; }
  957. ;
  958.  
  959. keyword_parameter_default:
  960.     /* epsilon */ { $$ = NULL; }
  961.     |    EQUAL expression { free($1); $$ = $2; }
  962. ;
  963.  
  964. module_definition:
  965.     SYMBOL module_clauses_opt END module_opt symbol_opt
  966.     { if ($5) {
  967.           if (strcasecmp($1->chars, $5->chars) != 0) {
  968.           error($5->line, "mismatched name, ``%s'' isn't ``%s''",
  969.             $5->chars, $1->chars);
  970.           yacc_recover();
  971.           }
  972.           free($5);
  973.       } 
  974.       free($3);
  975.       $$ = (struct constituent *) set_namespace_name($2, $1);
  976.     }
  977. ;
  978.  
  979. module_opt:
  980.     /* empty */         { $$ = NULL; }
  981.     |    MODULE            { free($1); $$ = NULL; }
  982.  
  983. module_clauses_opt:
  984.     /* empty */        { $$ = make_define_module(); }
  985.     |    module_clauses
  986.     |    module_clauses SEMI    { $$ = $1; free($2); }
  987. ;
  988.  
  989. module_clauses:
  990.     use_clause
  991.     { $$ = add_use_clause(make_define_module(), $1); }
  992.     |    export_clause
  993.     { $$ = add_exports(make_define_module(), $1); }
  994.     |    create_clause
  995.     { $$ = add_creates(make_define_module(), $1); }
  996.     |    module_clauses SEMI use_clause
  997.     { $$ = add_use_clause($1, $3); free($2); }
  998.     |    module_clauses SEMI export_clause
  999.     { $$ = add_exports($1, $3); free($2); }
  1000.     |    module_clauses SEMI create_clause
  1001.     { $$ = add_creates($1, $3); free($2); }
  1002. ;
  1003.  
  1004. export_clause:
  1005.     EXPORT variable_names    { free($1); $$ = $2; }
  1006. ;
  1007.  
  1008. create_clause:
  1009.     CREATE variable_names    { free($1); $$ = $2; }
  1010. ;
  1011.  
  1012. use_clause:
  1013.     USE SYMBOL module_use_options
  1014.     { free($1); $$ = make_use_clause($2, $3); }
  1015. ;
  1016.  
  1017. module_use_options:
  1018.     /* empty */        { $$ = make_use_options(); }
  1019.     |    module_use_options COMMA module_use_option
  1020.     { free($2); $$ = add_use_option($1, $3); }
  1021. ;
  1022.  
  1023. module_use_option:
  1024.     prefix_option
  1025.     |    import_option
  1026.     |    exclude_option
  1027.     |    rename_option
  1028.     |    export_option
  1029. ;
  1030.  
  1031. prefix_option:
  1032.     PREFIX_OPTION STRING
  1033.     { $$ = make_prefix_option($2); free($1); }
  1034. ;
  1035.  
  1036. import_option:
  1037.     IMPORT_OPTION ALL
  1038.     { $$ = make_use_option(useopt_IMPORT_ALL); free($1); free($2); }
  1039.     |    IMPORT_OPTION LBRACE imports_opt RBRACE
  1040.     { $$ = (struct use_option *) $3; free($1); free($2); free($4); }
  1041. ;
  1042.  
  1043. imports_opt:
  1044.     /* empty */        { $$ = make_import_option(); }
  1045.     |    imports            { $$ = $1; }
  1046. ;
  1047.  
  1048. imports:
  1049.     SYMBOL
  1050.     { $$ = add_import(make_import_option(), $1, NULL); }
  1051.     |    SYMBOL ARROW SYMBOL
  1052.     { $$ = add_import(make_import_option(), $1, $3); free($2); }
  1053.     |    imports COMMA SYMBOL
  1054.     { $$ = add_import($1, $3, NULL); free($2); }
  1055.     |    imports COMMA SYMBOL ARROW SYMBOL    
  1056.     { $$ = add_import($1, $3, $5); free($2); free($4); }
  1057. ;
  1058.  
  1059. exclude_option:
  1060.     EXCLUDE_OPTION variable_name_set
  1061.     { $$ = make_exclude_option($2); free($1); }
  1062. ;
  1063.  
  1064. export_option:
  1065.     EXPORT_OPTION ALL
  1066.     { $$ = make_use_option(useopt_EXPORT_ALL); free($1); free($2); }
  1067.     |    EXPORT_OPTION variable_name_set
  1068.     { $$ = make_export_option($2); free($1); }
  1069. ;
  1070.  
  1071. rename_option:
  1072.     RENAME_OPTION LBRACE RBRACE
  1073.     { $$ = make_rename_option(make_renamings());
  1074.       free($1); free($2); free($3); }
  1075.     |    RENAME_OPTION LBRACE rename_specs RBRACE
  1076.     { $$ = make_rename_option($3); free($1); free($2); free($4); }
  1077. ;
  1078.  
  1079. rename_specs:
  1080.     SYMBOL ARROW SYMBOL
  1081.     { $$ = add_renaming(make_renamings(), $1, $3); free($2); }
  1082.     |    rename_specs COMMA SYMBOL ARROW SYMBOL
  1083.     { $$ = add_renaming($1, $3, $5); free($2); free($4); }
  1084. ;
  1085.  
  1086. variable_name_set:
  1087.     LBRACE RBRACE    { $$ = make_variable_names(); free($1); free($2); }
  1088.     |    LBRACE variable_names RBRACE
  1089.     { $$ = $2; free($1); free($3); }
  1090. ;
  1091.  
  1092. variable_names:
  1093.     SYMBOL        { $$ = add_variable_name(make_variable_names(), $1); }
  1094.     |    variable_names COMMA SYMBOL
  1095.     { $$ = add_variable_name($1, $3); free($2); }
  1096. ;
  1097.  
  1098. library_definition:
  1099.     SYMBOL library_clauses_opt END library_opt symbol_opt
  1100.     { if ($5) {
  1101.           if (strcasecmp($1->chars, $5->chars) != 0) {
  1102.           error($5->line, "mismatched name, ``%s'' isn't ``%s''",
  1103.             $5->chars, $1->chars);
  1104.           yacc_recover();
  1105.           }
  1106.           free($5);
  1107.       } 
  1108.       free($3);
  1109.       $$ = (struct constituent *) set_namespace_name($2, $1);
  1110.     }
  1111. ;
  1112.  
  1113. library_opt:
  1114.     /* empty */         { $$ = NULL; }
  1115.     |    LIBRARY            { free($1); $$ = NULL; }
  1116.  
  1117. library_clauses_opt:
  1118.     /* empty */        { $$ = make_define_library(); }
  1119.     |    library_clauses
  1120.     |    library_clauses SEMI    { $$ = $1; free($2); }
  1121. ;
  1122.  
  1123. library_clauses:
  1124.     use_clause
  1125.     { $$ = add_use_clause(make_define_library(), $1); }
  1126.     |    export_clause
  1127.     { $$ = add_exports(make_define_library(), $1); }
  1128.     |    library_clauses SEMI use_clause
  1129.     { $$ = add_use_clause($1, $3); free($2); }
  1130.     |    library_clauses SEMI export_clause
  1131.     { $$ = add_exports($1, $3); free($2); }
  1132. ;
  1133.  
  1134.  
  1135. block_opt:    { $$ = NULL; } | BLOCK { free($1); $$ = NULL; } ;
  1136. case_opt:    { $$ = NULL; } | CASE { free($1); $$ = NULL; } ;
  1137. if_opt:        { $$ = NULL; } | IF { free($1); $$ = NULL; } ;
  1138. for_opt:    { $$ = NULL; } | FOR { free($1); $$ = NULL; } ;
  1139. select_opt:    { $$ = NULL; } | SELECT { free($1); $$ = NULL; } ;
  1140. unless_opt:    { $$ = NULL; } | UNLESS { free($1); $$ = NULL; } ;
  1141. until_opt:    { $$ = NULL; } | UNTIL { free($1); $$ = NULL; } ;
  1142. while_opt:    { $$ = NULL; } | WHILE { free($1); $$ = NULL; } ;
  1143. class_opt:    { $$ = NULL; } | CLASS { free($1); $$ = NULL; } ;
  1144. method_opt:    { $$ = NULL; } | METHOD { free($1); $$ = NULL; } ;
  1145. semi_opt:    { $$ = NULL; } | SEMI { free($1); $$ = NULL; } ;
  1146. arrow_opt:    { $$ = NULL; } | ARROW { free($1); $$ = NULL; } ;
  1147.  
  1148. symbol_opt:    { $$ = NULL; } | SYMBOL { $$ = $1; } ;
  1149. by_part_opt:    { $$ = NULL; } | by_part { $$ = $1; } ;
  1150. else_part_opt:    { $$ = NULL; } | else_part { $$ = $1; } ;
  1151. final_part_opt:    { $$ = NULL; } | final_part { $$ = $1; } ;
  1152.  
  1153. %%
  1154.  
  1155. static void yyerror(char *msg)
  1156. {
  1157.     if (yylval.token)
  1158.     error(yylval.token->line, "%s at or before `%s'\n",
  1159.           msg, yylval.token->chars);
  1160.     else
  1161.     error(line_count, "%s at end-of-file\n", msg);
  1162.     yacc_recover();
  1163. }
  1164.  
  1165. static boolean verify_symbol_aux(struct id *id, struct token *token)
  1166. {
  1167.     if (token) {
  1168.     int line = token->line;
  1169.     char *ptr = token->chars;
  1170.  
  1171.     if (*ptr == '\\')
  1172.         ptr++;
  1173.  
  1174.     if (strcasecmp(id->symbol->name, ptr)) {
  1175.         error(line, "mismatched name, ``%s'' isn't ``%s''",
  1176.           token->chars, id->symbol->name);
  1177.         free(token);
  1178.         return TRUE;
  1179.     }
  1180.     else
  1181.         free(token);
  1182.     }
  1183.     return FALSE;
  1184. }
  1185.  
  1186. static void yacc_recover()
  1187. {
  1188.     while (yychar) {
  1189.     struct token_list *rlist = yacc_recovery_list;
  1190.     while (rlist)
  1191.         if (rlist->token == yychar)
  1192.         return;
  1193.         else
  1194.         rlist = rlist->next;
  1195.     yychar = yylex();
  1196.     }
  1197.     yyclearin;
  1198. }
  1199.  
  1200. static void push_yacc_recovery(int token)
  1201. {
  1202.     struct token_list *newrec;
  1203.  
  1204.     newrec = malloc(sizeof(*newrec));
  1205.     newrec->token = token;
  1206.     newrec->next = yacc_recovery_list;
  1207.     yacc_recovery_list = newrec;
  1208. }
  1209.  
  1210. static void pop_yacc_recoveries(int count)
  1211. {
  1212.     for ( ; count-- > 0; )
  1213.     yacc_recovery_list = yacc_recovery_list->next;
  1214. }
  1215.  
  1216.